# Custom Component

<EpicVideo url="https://www.epicreact.dev/workshops/react-fundamentals/custom-component" />

👨‍💼 We want to reduce duplication here by making a custom `<Box />` component
that renders a div, accepts all the props and merges the given `style` and
`className` props with the shared values.

I should be able to use it like so:

```tsx
<Box className="box--small" style={{ backgroundColor: 'lightblue' }}>
	small lightblue box
</Box>
```

The `box` className and `fontStyle: 'italic'` style should be applied
automatically by the `<Box />` component which should then merge that default
with the values that come from props.

How you go about implementing it is part of the fun (aka "learning" 😉). You may
come up with something completely different from how I do it and that's great
for your learning. When you're done, these two ultimately render _exactly_ the
same thing:

```tsx
// before:
<div
  className="box box--small"
  style={{fontStyle: 'italic', backgroundColor: 'lightblue'}}
>
  small lightblue box
</div>

// after:
<Box className="box--small" style={{backgroundColor: 'lightblue'}}>
  small lightblue box
</Box>
```

And I should be able to switch the `div` for a `Box` for the medium and large
boxes as well.

💰 Here's a quick tip for the TypeScript part of this. When you want to wrap an
element to basically simulate that element + a little functionality (like in our
case), you'll want to borrow the type definition for that element from React.
Here's how you do that (for a `span` element rather than `div`):

```tsx
function MySpan(props: React.ComponentProps<'span'>) {
	return <span {...props} />
}
```

And now you'll get type safety and autocomplete for all the HTML attributes
accepted by a span element.
